package com.novax.ex.activity.provider.controller;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.novax.ex.activity.infrastructure.entity.MallProduct;
import com.novax.ex.activity.infrastructure.entity.MallProductMemos;
import com.novax.ex.activity.open.api.inner.MallProductInnerApi;
import com.novax.ex.activity.open.model.query.MallProductQuery;
import com.novax.ex.activity.open.model.request.MallProductMemosRequest;
import com.novax.ex.activity.open.model.request.MallProductRequest;
import com.novax.ex.activity.open.model.response.MallProductMemosResponse;
import com.novax.ex.activity.open.model.response.MallProductResponse;
import com.novax.ex.activity.provider.handler.provider.MallProductProvider;
import com.novax.ex.activity.provider.service.MallProductMemosService;
import com.novax.ex.activity.provider.service.MallProductService;
import com.novax.ex.common.constant.CommonConstants;
import com.novax.ex.common.constant.InternationalCode;
import com.novax.ex.common.constant.StatusCode;
import com.novax.ex.common.enums.MallProductMemosOperation;
import com.novax.ex.common.enums.MallProductStatus;
import com.novax.ex.common.results.ReturnResult;
import com.novax.ex.common.util.CopyUtils;
import com.novax.ex.common.util.PageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RestController;

import jakarta.annotation.Resource;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Description:商品配置
 *
 * @author Deucalion@novax.email
 * @date 2023/2/21 17:21
 */
@Slf4j
@RestController
public class MallProductController extends BaseActivityController implements MallProductInnerApi {
    @Resource
    private MallProductService mallProductService;
    @Resource
    private MallProductMemosService mallProductMemosService;
    @Resource
    private MallProductProvider mallProductProvider;

    @Override
    public ReturnResult add(String language, Long adminId, MallProductRequest request, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            return ReturnResult.fail(getInternational(language, InternationalCode.LACK_VALUE));
        }
        if(request.getTitle().length() > 128){
            String content = MessageFormat.format(getInternational(language, InternationalCode.OUT_OF_LENGTH_LIMIT), "title",128);
            return new ReturnResult<>(StatusCode.ERROR,content);
        }
        try {
            MallProduct entity = BeanUtil.copyProperties(request, MallProduct.class);
            entity.setId(null);
            entity.setPrice(entity.getPrice().setScale(0, BigDecimal.ROUND_DOWN));
            entity.setStatus(CommonConstants.Either.LATTER);
            entity.setCreator(adminId);
            if(null != entity.getCost()){
                entity.setCost(entity.getCost().setScale(7, BigDecimal.ROUND_DOWN));
            }
            boolean result = mallProductService.addProduct(entity);
            if (result) {
                return ReturnResult.success(getInternational(language, InternationalCode.OPERATION_SUCCESS));
            }
            return ReturnResult.fail(getInternational(language, InternationalCode.OPERATION_ERROR));
        }catch (Exception e){
            return ReturnResult.fail(getInternational(language, InternationalCode.OPERATION_ERROR));
        }
    }

    @Override
    public ReturnResult modify(String language, Long adminId, MallProductRequest request, BindingResult bindingResult) {
        // 缺少必填项
        if(null == request.getId()){
            return ReturnResult.fail(getInternational(language, InternationalCode.LACK_VALUE));
        }
        if(bindingResult.hasErrors()){
            return ReturnResult.fail(getInternational(language, InternationalCode.LACK_VALUE));
        }
        if(request.getTitle().length() > 128){
            String content = MessageFormat.format(getInternational(language, InternationalCode.OUT_OF_LENGTH_LIMIT), "title",128);
            return new ReturnResult<>(StatusCode.ERROR,content);
        }
        MallProduct old = mallProductService.find(request.getId());
        if(null == old){
            return ReturnResult.fail(getInternational(language, InternationalCode.NOT_EXIST));
        }
        MallProduct entity = BeanUtil.copyProperties(request, MallProduct.class);
        entity.setTitle(null);
        entity.setCurrency(null);
        entity.setCostCurrency(null);
        entity.setPrice(entity.getPrice().setScale(0, BigDecimal.ROUND_DOWN));
        entity.setUpdater(adminId);
        if(null != entity.getCost()){
            entity.setCost(entity.getCost().setScale(7, BigDecimal.ROUND_DOWN));
        }
        if(entity.getStockCount() == 0){
            entity.setStatus(MallProductStatus.down.getStatus());
        }
        boolean result = mallProductService.modifySelective(entity);
        if (result) {
            MallProduct data = BeanUtil.copyProperties(request, MallProduct.class);
            if(null != entity.getPrice() && old.getPrice().compareTo(entity.getPrice()) != 0){
                mallProductMemosService.changePrice(request.getId(),
                        adminId,old.getPrice(),entity.getPrice(), MallProductMemosOperation.sellPrice.getStatus());
                mallProductProvider.sendUpdatePrice(JSON.toJSONString(data));
            }
            if(null != entity.getCost() && old.getCost().compareTo(entity.getCost()) != 0){
                mallProductMemosService.changePrice(request.getId(),
                        adminId,old.getCost(),entity.getCost(), MallProductMemosOperation.costPrice.getStatus());
                mallProductProvider.sendUpdateCost(JSON.toJSONString(data));
            }
            return ReturnResult.success(getInternational(language, InternationalCode.OPERATION_SUCCESS));
        }
        return ReturnResult.fail(getInternational(language, InternationalCode.OPERATION_ERROR));
    }

    @Override
    public ReturnResult remove(Long id, String language, Long adminId) {
        MallProduct old = mallProductService.find(id);
        if(null == old){
            return ReturnResult.fail(getInternational(language, InternationalCode.NOT_EXIST));
        }
        boolean result = mallProductService.removeById(id,adminId);
        if (result) {
            mallProductProvider.sendDel(JSON.toJSONString(old));
            return ReturnResult.success(getInternational(language, InternationalCode.OPERATION_SUCCESS));
        }
        return ReturnResult.fail(getInternational(language, InternationalCode.OPERATION_ERROR));
    }

    @Override
    public ReturnResult productStatusChange(Long id, String language, Long adminId, Integer status) {
        if(null == id || null == status){
            return ReturnResult.fail(getInternational(language, InternationalCode.LACK_VALUE));
        }
        if(status < 1 || status > 2){
            return ReturnResult.fail(getInternational(language, InternationalCode.REQUIREMENT));
        }
        MallProduct old = mallProductService.find(id);
        if(null == old){
            return ReturnResult.fail(getInternational(language, InternationalCode.NOT_EXIST));
        }
        if(old.getStockCount() <= 0 && MallProductStatus.up.getStatus().equals(status)){
            return ReturnResult.fail(getInternational(language, InternationalCode.UNDERSTOCK));
        }
        MallProduct entity = new MallProduct();
        entity.setId(id);
        entity.setStatus(status);
        entity.setUpdater(adminId);
        boolean result = mallProductService.modifySelective(entity);
        if (result) {
            if(MallProductStatus.up.getStatus().equals(status)){
                old.setStatus(status);
                mallProductProvider.sendPutOn(JSON.toJSONString(old));
            }
            return ReturnResult.success(getInternational(language, InternationalCode.OPERATION_SUCCESS));
        }
        return ReturnResult.fail(getInternational(language, InternationalCode.OPERATION_ERROR));
    }

    @Override
    public ReturnResult<PageUtil<MallProductResponse>> list(String language, MallProductQuery query) {
        PageUtil<MallProductResponse> pages = new PageUtil<>(query);
        Map<String, Object> condition = new HashMap<>();
        condition.put("query", query);
        pages.setCondition(condition);
        mallProductService.findPage(pages,MallProductResponse.class);
        return ReturnResult.success(getInternational(language, InternationalCode.QUERY_SUCCESS), pages);
    }

    @Override
    public ReturnResult<MallProductResponse> detail(Long id, String language) {
        MallProduct old = mallProductService.find(id);
        if(null == old){
            return ReturnResult.fail(getInternational(language, InternationalCode.NOT_EXIST));
        }
        MallProductResponse response = BeanUtil.copyProperties(old, MallProductResponse.class);
        return ReturnResult.success(getInternational(language, InternationalCode.QUERY_SUCCESS), response);
    }

    @Override
    public ReturnResult<List<MallProductMemosResponse>> memo(String language, Long mallProductId) {
        Map<String, Object> param = new HashMap<>();
        param.put("mallProductId",mallProductId);
        List<MallProductMemos> list = mallProductMemosService.findList(param);
        List<MallProductMemosResponse> responses = CopyUtils.copyList(list, MallProductMemosResponse.class);
        return ReturnResult.success(getInternational(language, InternationalCode.QUERY_SUCCESS), responses);
    }

    @Override
    public ReturnResult memoAdd(String language, Long adminId, MallProductMemosRequest request) {
        if(null == request.getMallProductId() || null == request.getMemo()){
            return ReturnResult.fail(getInternational(language, InternationalCode.LACK_VALUE));
        }
        MallProduct product = mallProductService.find(request.getMallProductId());
        if(null == product){
            return ReturnResult.fail(getInternational(language, InternationalCode.NOT_EXIST));
        }
        boolean result = mallProductMemosService.memoAdd(adminId,request.getMallProductId(),request.getMemo());
        if (result) {
            return ReturnResult.success(getInternational(language, InternationalCode.OPERATION_SUCCESS));
        }
        return ReturnResult.fail(getInternational(language, InternationalCode.OPERATION_ERROR));
    }
}
